﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using Red.Controls.Shell;
using Red.Controls.Utils;
using Red.Launcher.Menus.ExternalApplications;
using Dialog = Red.Launcher.Utilities.Dialog;
using ViewModel = Red.Launcher.ViewModels.ExternalApplications;

namespace Red.Launcher
{
    public partial class ExternalApplicationsView : UserControl, IDragSource
    {
        #region Private Data

        private readonly ViewModel.Manager _applicationManager = new ViewModel.Manager();
        private readonly Dialog.Manager _dialogs = new Dialog.Manager();

        #endregion Private Data

        #region Public Properties

        public Controls.Utils.DragDrop DragDrop { get; private set; } = new Controls.Utils.DragDrop();

        public ViewModel.Manager Manager => _applicationManager;

        #endregion Public Properties

        #region C-Tor

        partial void InitializeAnalytics();

        public ExternalApplicationsView()
        {
            InitializeComponent();

            DataContext = _applicationManager;

            Loaded += ExternalApplicationsView_Loaded;
            _addApplication.Click += _addApplication_Click;
            _applicationList.MouseDown += _applicationList_MouseDown;

            DragDrop.Initialize( this );

            InitializeAnalytics();
        }

        #endregion C-Tor

        #region Public Methods

        public void WriteToSettings()
        {
            _applicationManager.Save();
        }

        public void LoadFromSettings()
        {
            _applicationManager.Load();
        }

        #endregion Public Methods

        #region Event Handlers

        private void ExternalApplicationsView_Loaded( object sender, RoutedEventArgs e )
        {
            Window parentWindow = Window.GetWindow( this );
            _dialogs.Owner = parentWindow;
        }

        private void _addApplication_Click( object sender, RoutedEventArgs e )
        {
            _dialogs.Show<ApplicationConfigurationDialog, ViewModel.Application>
            (
                typeof( ViewModel.Application ),
                ( Dialog.IEvents dialog, Dialog.CloseReason reason ) =>
                {
                    if ( reason == Dialog.CloseReason.Ok )
                    {
                        ApplicationConfigurationDialog appDialog = (ApplicationConfigurationDialog)dialog;
                        _applicationManager.Applications.Add( appDialog.Application );
                    }
                }
            );
        }

        private void _applicationList_MouseDown( object sender, MouseButtonEventArgs e )
        {
            DataGrid grid = (DataGrid)sender;
            if ( grid.SelectedItem != null )
            {
                DataGridRow row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromItem( grid.SelectedItem );
                if ( !row.IsMouseOver )
                {
                    row.IsSelected = false;
                }
            }
        }

        private void _applicationList_RowMouseDoubleClick( object sender, MouseButtonEventArgs e )
        {
            ViewModel.Application application = ((FrameworkElement)sender).DataContext as ViewModel.Application;
            _applicationManager.Run( application );
        }

        private void Run_Clicked( object sender, RoutedEventArgs e )
        {
            ViewModel.Application application = ((FrameworkElement)sender).DataContext as ViewModel.Application;
            _applicationManager.Run( application );
        }

        private void Edit_Clicked( object sender, RoutedEventArgs e )
        {
            ViewModel.Application application = ((FrameworkElement)sender).DataContext as ViewModel.Application;

            if( application != null )
            {
                _dialogs.Show<ApplicationConfigurationDialog, ViewModel.Application>
                (
                    application.Path,
                    application,
                    ( Dialog.IEvents dialog, Dialog.CloseReason reason ) =>
                    {
                        if ( reason == Dialog.CloseReason.Ok )
                        {
                            ApplicationConfigurationDialog appDialog = (ApplicationConfigurationDialog)dialog;
                            application.Copy( appDialog.Application );
                        }
                    }
                );
            }
        }

        private void Delete_Clicked( object sender, RoutedEventArgs e )
        {
            ViewModel.Application application = ((FrameworkElement)sender).DataContext as ViewModel.Application;

            if ( application != null )
            {
                if ( RedMessageBox.Show( this, RedDialogType.YesNo, $"Are you sure you want to remove the shortcut for '{application.Name}'?", "Remove external application" ) )
                {
                    _applicationManager.Applications.Remove( application );
                }
            }
        }

        #endregion Event Handlers

        #region IDragSource

        public DragDropEffects GetDragObject( Point point, out DependencyObject dragObject, out object dragData )
        {
            HitTestResult hitTestResult = VisualTreeHelper.HitTest( this, point );

            if ( hitTestResult.VisualHit != null )
            {
                DataGridRow row = Helpers.FindVisualAncestorOfType<DataGridRow>( hitTestResult.VisualHit );

                if ( row != null )
                {
                    dragObject = row;
                    dragData = row.DataContext;
                    return DragDropEffects.Copy;
                }
            }

            dragObject = null;
            dragData = null;
            return DragDropEffects.None;
        }

        public void OnDragStart( DragData data ) { }

        public void OnDragStop( DragData data, DragDropEffects mode ) { }

        #endregion IDragSource
    }
}
